home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / gtlayout-source.lha / LTP_TabClass.c < prev    next >
C/C++ Source or Header  |  1995-09-24  |  18KB  |  797 lines

  1. /*  GadTools layout toolkit
  2. **
  3. **  Copyright © 1993-1995 by Olaf `Olsen' Barthel
  4. **  Freely distributable.
  5. **
  6. **    :ts=4
  7. */
  8.  
  9. #include "gtlayout_global.h"
  10.  
  11. //#define DB(x)    x
  12. #define DB(x)    ;
  13.  
  14. #if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  15.  
  16. #define TIA_Labels        (TAG_USER+0x90000)
  17. #define TIA_Font        (TAG_USER+0x90001)
  18. #define TIA_Screen        (TAG_USER+0x90002)
  19. #define TIA_Index        (TAG_USER+0x90003)
  20. #define TIA_DrawInfo    (TAG_USER+0x90004)
  21. #define TIA_SizeType    (TAG_USER+0x90005)
  22.  
  23. STATIC VOID __regargs
  24. DeleteBitMap(struct BitMap *BitMap,BOOL Chip)
  25. {
  26.     if(V39 && !Chip)
  27.         FreeBitMap(BitMap);
  28.     else
  29.     {
  30.         if(BitMap)
  31.         {
  32.             WORD i;
  33.  
  34.             for(i = 0 ; i < BitMap->Depth ; i++)
  35.                 FreeVec(BitMap->Planes[i]);
  36.  
  37.             FreeVec(BitMap);
  38.         }
  39.     }
  40. }
  41.  
  42. STATIC struct BitMap * __regargs
  43. CreateBitMap(UWORD Width,UWORD Height,UBYTE Depth,struct BitMap *Friend,BOOL Chip)
  44. {
  45.     struct BitMap *BitMap;
  46.  
  47.     if(V39 && !Chip)
  48.         BitMap = AllocBitMap(Width,Height,Depth,NULL,Friend);
  49.     else
  50.     {
  51.         if(BitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap),MEMF_ANY | MEMF_PUBLIC))
  52.         {
  53.             LONG PageSize;
  54.             WORD i;
  55.  
  56.             InitBitMap(BitMap,Depth,Width,Height);
  57.  
  58.             PageSize = BitMap->BytesPerRow * BitMap->Rows;
  59.  
  60.             for(i = 0 ; i < Depth ; i++)
  61.             {
  62.                 if(!(BitMap->Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP)))
  63.                 {
  64.                     WORD j;
  65.  
  66.                     for(j = 0 ; j < i ; j++)
  67.                         FreeVec(BitMap->Planes[j]);
  68.  
  69.                     FreeVec(BitMap);
  70.  
  71.                     return(NULL);
  72.                 }
  73.             }
  74.         }
  75.     }
  76.  
  77.     return(BitMap);
  78. }
  79. /*    // not used
  80. STATIC VOID __regargs
  81. NotifyIndex(struct IClass *class,struct Gadget *gadget,struct GadgetInfo *GInfo,struct opUpdate *msg,LONG Index)
  82. {
  83.     struct TagItem Tags[3];
  84.  
  85.     Tags[0].ti_Tag    = GA_ID;
  86.     Tags[0].ti_Data    = gadget->GadgetID;
  87.     Tags[1].ti_Tag    = TIA_Index;
  88.     Tags[1].ti_Data    = Index;
  89.     Tags[2].ti_Tag    = TAG_DONE;
  90.  
  91.     DoSuperMethod(class,(Object *)gadget,OM_NOTIFY,Tags,GInfo,((msg->MethodID == OM_UPDATE) ? (msg->opu_Flags) : 0L));
  92. }
  93. */
  94. STATIC VOID __regargs
  95. RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,UWORD Pull,BOOL Disabled)
  96. {
  97.     UWORD    Width,Height;
  98.     LONG    i;
  99.     UWORD    Pen;
  100.  
  101.     Width    = Info->TabWidth;
  102.     Height    = Info->TabHeight;
  103.  
  104.     SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
  105.  
  106.     for(i = 0 ; i < 4 ; i++)
  107.     {
  108.         if(i & 1)
  109.             Pen = SHADOWPEN;
  110.         else
  111.             Pen = SHINEPEN;
  112.  
  113.         SetAPen(&Info->RPort,Pens[Pen]);
  114.  
  115.         Move(&Info->RPort,0,Height - 1 - i);
  116.         Draw(&Info->RPort,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
  117.     }
  118.  
  119.     for(i = Info->Count - 1 ; i >= 0 ; i--)
  120.     {
  121.         if(i != Info->Current)
  122.             BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
  123.     }
  124.  
  125.     BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
  126.  
  127.     WaitBlit();
  128.  
  129.     BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
  130. /*    // Intuition ghosts images all by itself
  131.     if(Disabled)
  132.     {
  133.         SetAPen(RPort,Pens[BLOCKPEN]);
  134.         SetDrMd(RPort,JAM1);
  135.  
  136.         SetAfPt(RPort,(UWORD *)&ghostingPat,1);
  137.         RectFill(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->LeftEdge + gadget->Width - 1,gadget->TopEdge + gadget->Height - 1);
  138.         SetAfPt(RPort,NULL,0);
  139.     }
  140. */
  141. }
  142.  
  143. STATIC ULONG __regargs
  144. SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  145. {
  146.     TabInfo            *Info = INST_DATA(class,gadget);
  147.     struct TagItem    *Tag;
  148.     BOOL             NeedRefresh = FALSE;
  149.     BOOL             Disabled;
  150.  
  151.     Disabled = gadget->Flags & GFLG_DISABLED;
  152.  
  153.     if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
  154.     {
  155.         if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
  156.         {
  157.             Disabled = Tag->ti_Data;
  158.  
  159.             NeedRefresh = TRUE;
  160.         }
  161.     }
  162.  
  163.     if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
  164.     {
  165.         LONG Index = Tag->ti_Data;
  166.  
  167.         if(Index >= Info->Count)
  168.             Index = Info->Count - 1;
  169.  
  170.         if(Index != Info->Current)
  171.         {
  172.             Info->Initial = Info->Current = Index;
  173.  
  174.             NeedRefresh = TRUE;
  175.         }
  176.     }
  177.  
  178.     if(NeedRefresh)
  179.     {
  180.         struct RastPort *RPort;
  181.  
  182.         if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
  183.         {
  184.             RenderTabs(RPort,gadget,Info,SetInfo->ops_GInfo->gi_DrInfo->dri_Pens,0,Disabled);
  185.  
  186. /*            NotifyIndex(class,gadget,SetInfo->ops_GInfo,(struct opUpdate *)SetInfo,Info->Current);*/
  187.  
  188.             ReleaseGIRPort(RPort);
  189.         }
  190.     }
  191.  
  192.     return(DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo));
  193. }
  194.  
  195. STATIC ULONG __regargs
  196. RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
  197. {
  198.     TabInfo *Info = INST_DATA(class,gadget);
  199.  
  200.     RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
  201.  
  202.     return(TRUE);
  203. }
  204.  
  205. STATIC ULONG __regargs
  206. DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
  207. {
  208.     TabInfo *Info = INST_DATA(class,gadget);
  209.  
  210.     if(Info->Mask || Info->Tabs || Info->BitMap)
  211.         WaitBlit();
  212.  
  213.     if(Info->Mask)
  214.         FreeVec(Info->Mask);
  215.  
  216.     if(Info->Tabs)
  217.     {
  218.         LONG i;
  219.  
  220.         for(i = 0 ; i < Info->Count ; i++)
  221.             DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
  222.  
  223.         FreeVec(Info->Tabs);
  224.     }
  225.  
  226.     DeleteBitMap(Info->BitMap,FALSE);
  227.  
  228.     return(DoSuperMethodA(class,(Object *)gadget,msg));
  229. }
  230.  
  231. STATIC ULONG __regargs
  232. NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
  233. {
  234.     if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
  235.     {
  236.         TabInfo            *Info = INST_DATA(class,gadget);
  237.         struct TagItem    *Tag,*TagList = SetInfo->ops_AttrList;
  238.         struct TextAttr    *FontAttr;
  239.         UWORD             Width,Height;
  240.         struct DrawInfo    *DrawInfo;
  241.         STRPTR            *Labels;
  242.         struct Screen    *Screen;
  243.  
  244.         Width = Height = 0;
  245.         FontAttr = NULL;
  246.         DrawInfo = NULL;
  247.         Labels = NULL;
  248.         Screen = NULL;
  249.  
  250.         memset(Info,0,sizeof(TabInfo));
  251.  
  252.         while(Tag = NextTagItem(&TagList))
  253.         {
  254.             switch(Tag->ti_Tag)
  255.             {
  256.                 case TIA_Labels:
  257.                     Labels = (STRPTR *)Tag->ti_Data;
  258.                     break;
  259.  
  260.                 case TIA_Screen:
  261.                     Screen = (struct Screen *)Tag->ti_Data;
  262.                     break;
  263.  
  264.                 case TIA_Font:
  265.                     FontAttr = (struct TextAttr *)Tag->ti_Data;
  266.                     break;
  267.  
  268.                 case TIA_Index:
  269.                     Info->Current = Tag->ti_Data;
  270.                     break;
  271.  
  272.                 case TIA_DrawInfo:
  273.                     DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  274.                     break;
  275.  
  276.                 case GA_Width:
  277.                     Width = Tag->ti_Data;
  278.                     break;
  279.  
  280.                 case GA_Height:
  281.                     Height = Tag->ti_Data;
  282.                     break;
  283.             }
  284.         }
  285.  
  286.         if(Labels)
  287.         {
  288.             while(Labels[Info->Count])
  289.                 Info->Count++;
  290.         }
  291.  
  292.         if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
  293.         {
  294.             struct TextFont *Font;
  295.  
  296.             if(Font = OpenFont(FontAttr))
  297.             {
  298.                 struct RastPort *RPort = &Info->RPort;
  299.  
  300.                 InitRastPort(RPort);
  301.  
  302.                 SetFont(RPort,Font);
  303.  
  304.                 if(Height >= RPort->TxHeight + 11)
  305.                 {
  306.                     LONG i,Len,MaxWidth,Remain;
  307.                     UWORD Lean;
  308.  
  309.                     if(Info->Current < 0)
  310.                         Info->Current = 0;
  311.                     else
  312.                     {
  313.                         if(Info->Current >= Info->Count)
  314.                             Info->Current = Info->Count - 1;
  315.                     }
  316.  
  317.                     Lean = (TextLength(RPort,"A",1) + 1) / 2;
  318.  
  319.                     Info->Thick    = DrawInfo->dri_Resolution.Y / DrawInfo->dri_Resolution.X;
  320. //                    Info->Thick    = 2;
  321.  
  322.                     if(Info->Thick < 1)
  323.                         Info->Thick = 1;
  324.  
  325.                     for(i = MaxWidth = 0 ; i < Info->Count ; i++)
  326.                     {
  327.                         if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  328.                             MaxWidth = Len;
  329.                     }
  330.  
  331.                     MaxWidth = 2 + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + 2;
  332.  
  333.                     Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
  334.  
  335.                     if(Remain >= Info->Count - 1)
  336.                     {
  337.                         if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
  338.                         {
  339.                             STATIC BYTE PenNumbers[] =
  340.                             {
  341.                                 BACKGROUNDPEN,
  342.                                 SHINEPEN,
  343.                                 SHADOWPEN,
  344.                                 TEXTPEN
  345.                             };
  346.  
  347.                             struct BitMap __aligned     Mask;
  348.                             BOOL                     GotIt = TRUE;
  349.                             UWORD                     Depth;
  350.                             LONG                     MaxPen;
  351.                             UWORD                    *Pens = DrawInfo->dri_Pens;
  352.  
  353.                             for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
  354.                             {
  355.                                 if(Pens[PenNumbers[i]] > MaxPen)
  356.                                     MaxPen = Pens[PenNumbers[i]];
  357.                             }
  358.  
  359.                             for(i = 1 ; i < 9 ; i++)
  360.                             {
  361.                                 if(MaxPen < (1 << i))
  362.                                 {
  363.                                     Depth = i;
  364.                                     break;
  365.                                 }
  366.                             }
  367.  
  368.                             Info->TabWidth    = MaxWidth;
  369.                             Info->TabHeight    = 4 + RPort->TxHeight + 5;
  370.  
  371.                             InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
  372.  
  373.                             Mask.Planes[1] = NULL;
  374.  
  375.                             for(i = 0 ; GotIt && i < 2 ; i++)
  376.                             {
  377.                                 if(!(Mask.Planes[i] = (PLANEPTR)AllocVec(Mask.BytesPerRow * Mask.Rows,MEMF_CHIP)))
  378.                                     GotIt = FALSE;
  379.                             }
  380.  
  381.                             for(i = 0 ; GotIt && i < Info->Count ; i++)
  382.                             {
  383.                                 if(!(Info->Tabs[i].BitMap = CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
  384.                                     GotIt = FALSE;
  385.                             }
  386.  
  387.                             if(V39)
  388.                                 Depth = GetBitMapAttr(Screen->RastPort.BitMap,BMA_DEPTH);
  389.                             else
  390.                                 Depth = Screen->RastPort.BitMap->Depth;
  391.  
  392.                             if(!(Info->BitMap = CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
  393.                                 GotIt = FALSE;
  394.  
  395.                             if(GotIt)
  396.                             {
  397.                                 struct TmpRas     TmpRas;
  398.                                 LONG             j,Len,Offset,Pos;
  399.  
  400.                                 InitTmpRas(&TmpRas,Mask.Planes[1],RASSIZE(Info->TabWidth,Info->TabHeight));
  401.  
  402.                                 RPort->TmpRas    = &TmpRas;
  403.                                 RPort->BitMap    = &Mask;
  404.  
  405.                                 SetRast(RPort,0);
  406.                                 SetAPen(RPort,1);
  407.                                 SetDrMd(RPort,JAM1);
  408.  
  409.                                 Move(RPort,0,Info->TabHeight - 1);
  410.                                 Draw(RPort,Lean - 1,0);
  411.  
  412.                                 Move(RPort,Lean,0);
  413.                                 Draw(RPort,Info->TabWidth - (Lean + 1),0);
  414.  
  415.                                 Move(RPort,Info->TabWidth - Lean,0);
  416.                                 Draw(RPort,Info->TabWidth - 1,Info->TabHeight - 1);
  417.  
  418.                                 Move(RPort,0,Info->TabHeight - 1);
  419.                                 Draw(RPort,Info->TabWidth - 1,Info->TabHeight - 1);
  420.  
  421.                                 Flood(RPort,1,Info->TabWidth / 2,Info->TabHeight / 2);
  422.  
  423.                                 SetAPen(RPort,0);
  424.  
  425.                                 for(i = 0 ; i < 4 ; i++)
  426.                                 {
  427.                                     for(j = 0 ; j < 2 ; j++)
  428.                                         WritePixel(RPort,j,Info->TabHeight - 1 - i);
  429.  
  430.                                     for(j = 0 ; j < 2 ; j++)
  431.                                         WritePixel(RPort,Info->TabWidth - 1 - j,Info->TabHeight - 1 - i);
  432.                                 }
  433.  
  434.                                 WaitBlit();
  435.  
  436.                                 FreeVec(Mask.Planes[1]);
  437.  
  438.                                 RPort->TmpRas = NULL;
  439.  
  440.                                 Offset = (Width - Info->Thick * 5) / Info->Count;
  441.  
  442.                                 while(Offset > 0 && Offset * (Info->Count - 1) + Info->TabWidth >= Width - Info->Thick * 5)
  443.                                     Offset--;
  444.  
  445.                                 if(Offset > Info->TabWidth + Info->Thick)
  446.                                     Offset = Info->TabWidth + Info->Thick;
  447.  
  448.                                 Pos = 2 * Info->Thick;
  449.  
  450.                                 for(i = 0 ; i < Info->Count ; i++)
  451.                                 {
  452.                                     RPort->BitMap = Info->Tabs[i].BitMap;
  453.  
  454.                                     Info->Tabs[i].Left = Pos;
  455.                                     Pos += Offset;
  456.  
  457.                                     SetRast(RPort,Pens[BACKGROUNDPEN]);
  458.  
  459.                                     SetAPen(RPort,Pens[SHINEPEN]);
  460.  
  461.                                     for(j = 0 ; j < Info->Thick ; j++)
  462.                                     {
  463.                                         Move(RPort,2 + j,Info->TabHeight - 1);
  464.                                         Draw(RPort,2 + j + Lean - 1,0);
  465.                                     }
  466.  
  467.                                     Move(RPort,2 + Lean,0);
  468.                                     Draw(RPort,Info->TabWidth - (Lean + 1) - 2,0);
  469.  
  470.                                     SetAPen(RPort,Pens[SHADOWPEN]);
  471.  
  472.                                     for(j = 0 ; j < Info->Thick ; j++)
  473.                                     {
  474.                                         Move(RPort,Info->TabWidth - Lean - j - 2,0);
  475.                                         Draw(RPort,Info->TabWidth - 1 - j - 2,Info->TabHeight - 1);
  476.                                     }
  477.  
  478.                                     SetAPen(RPort,Pens[TEXTPEN]);
  479.                                     Len = strlen(Labels[i]);
  480.  
  481.                                     Move(RPort,(Info->TabWidth - TextLength(RPort,Labels[i],Len)) / 2,2 + RPort->TxBaseline);
  482.                                     Text(RPort,Labels[i],Len);
  483.                                 }
  484.  
  485.                                 Info->Mask = Mask.Planes[0];
  486.  
  487.                                 Info->Offset = Offset;
  488.  
  489.                                 Info->RPort.BitMap = Info->BitMap;
  490.  
  491.                                 CloseFont(Font);
  492.  
  493.                                 return((ULONG)gadget);
  494.                             }
  495.                         }
  496.                     }
  497.                 }
  498.  
  499.                 CloseFont(Font);
  500.             }
  501.         }
  502.  
  503.         CoerceMethod(class,(Object *)gadget,OM_DISPOSE);
  504.     }
  505.  
  506.     return(0);
  507. }
  508.  
  509. STATIC ULONG __regargs
  510. InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  511. {
  512.     TabInfo    *Info    = INST_DATA(class,gadget);
  513.     ULONG     Result    = GMR_MEACTIVE;
  514.     BOOL     Done    = FALSE;
  515.     WORD     x,y;
  516.  
  517.     x = InputInfo->gpi_Mouse.X;
  518.     y = InputInfo->gpi_Mouse.Y;
  519.  
  520.     if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  521.     {
  522.         if(InputInfo->gpi_IEvent->ie_Code == MENUDOWN)
  523.         {
  524.             Result    = GMR_NOREUSE;
  525.             Done    = TRUE;
  526.         }
  527.         else
  528.         {
  529.             if(InputInfo->gpi_IEvent->ie_Code == SELECTUP)
  530.             {
  531.                 Done = TRUE;
  532.  
  533.                 if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  534.                 {
  535.                     Result = GMR_REUSE | GMR_VERIFY;
  536.  
  537.                     *InputInfo->gpi_Termination = Info->Current;
  538.                 }
  539.                 else
  540.                     Result = GMR_NOREUSE;
  541.             }
  542.         }
  543.     }
  544.  
  545.     if(Result == GMR_NOREUSE)
  546.     {
  547.         struct RastPort    *RPort;
  548.  
  549.         if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  550.         {
  551.             Info->Current = Info->Initial;
  552.  
  553.             RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
  554.  
  555. /*            NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Info->Current);*/
  556.  
  557.             ReleaseGIRPort(RPort);
  558.         }
  559.     }
  560.  
  561.     if(!Done)
  562.     {
  563.         if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
  564.         {
  565.             LONG Index,i;
  566.  
  567.             for(Index = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  568.             {
  569.                 if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  570.                     Index = i;
  571.             }
  572.  
  573.             if(Index != Info->Current && Index != -1)
  574.             {
  575.                 struct RastPort    *RPort;
  576.  
  577.                 if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  578.                 {
  579.                     Info->Current = Index;
  580.  
  581.                     RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,2,gadget->Flags & GFLG_DISABLED);
  582.  
  583. /*                    NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Index);*/
  584.  
  585.                     ReleaseGIRPort(RPort);
  586.                 }
  587.             }
  588.         }
  589.     }
  590.  
  591.     return(Result);
  592. }
  593.  
  594. STATIC ULONG __regargs
  595. ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
  596. {
  597.     TabInfo            *Info = INST_DATA(class,gadget);
  598.     struct RastPort    *RPort;
  599.  
  600.     if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
  601.     {
  602.         LONG Current,i;
  603.         WORD x;
  604.  
  605.         x = InputInfo->gpi_Mouse.X;
  606.  
  607.         for(Current = -1, i = Info->Count - 1 ; i >= 0 ; i--)
  608.         {
  609.             if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
  610.                 Current = i;
  611.         }
  612.  
  613.         Info->Initial = Info->Current;
  614.  
  615.         if(Current != Info->Current && Current != -1)
  616.         {
  617.             Info->Current = Current;
  618.  
  619.             RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,2,gadget->Flags & GFLG_DISABLED);
  620.         }
  621.  
  622. /*        NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Info->Current);*/
  623.  
  624.         ReleaseGIRPort(RPort);
  625.  
  626.         return(GMR_MEACTIVE);
  627.     }
  628.     else
  629.         return(GMR_NOREUSE);
  630. }
  631.  
  632. STATIC ULONG __regargs
  633. InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
  634. {
  635.     TabInfo            *Info = INST_DATA(class,gadget);
  636.     struct RastPort    *RPort;
  637.     LONG             Index;
  638.  
  639.     if(InactiveInfo->gpgi_Abort)
  640.         Index = Info->Initial;
  641.     else
  642.         Index = Info->Current;
  643.  
  644.     if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
  645.     {
  646.         Info->Current = Index;
  647.  
  648.         RenderTabs(RPort,gadget,Info,InactiveInfo->gpgi_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
  649.  
  650. /*        NotifyIndex(class,gadget,InactiveInfo->gpgi_GInfo,(struct opUpdate *)InactiveInfo,Info->Current);*/
  651.  
  652.         ReleaseGIRPort(RPort);
  653.     }
  654.  
  655.     return(0);
  656. }
  657.  
  658. BOOL __stdargs
  659. LTP_ObtainTabSize(struct IBox *Box,...)
  660. {
  661.     va_list             VarArgs;
  662.     struct TagItem    *TagList,*Tag;
  663.     struct TextAttr    *FontAttr;
  664.     struct DrawInfo    *DrawInfo;
  665.     STRPTR            *Labels;
  666.     LONG             Count;
  667.     LONG             SizeType;
  668.     BOOL             Success;
  669.  
  670.     Success = FALSE;
  671.  
  672.     va_start(VarArgs,Box);
  673.  
  674.     TagList = (struct TagItem *)VarArgs;
  675.  
  676.     SizeType = GDOMAIN_NOMINAL;
  677.     FontAttr = NULL;
  678.     DrawInfo = NULL;
  679.     Labels = NULL;
  680.  
  681.     while(Tag = NextTagItem(&TagList))
  682.     {
  683.         switch(Tag->ti_Tag)
  684.         {
  685.             case TIA_Labels:
  686.                 Labels = (STRPTR *)Tag->ti_Data;
  687.                 break;
  688.  
  689.             case TIA_Font:
  690.                 FontAttr = (struct TextAttr *)Tag->ti_Data;
  691.                 break;
  692.  
  693.             case TIA_DrawInfo:
  694.                 DrawInfo = (struct DrawInfo *)Tag->ti_Data;
  695.                 break;
  696.  
  697.             case TIA_SizeType:
  698.                 SizeType = Tag->ti_Data;
  699.                 break;
  700.         }
  701.     }
  702.  
  703.     Count = 0;
  704.  
  705.     if(Labels)
  706.     {
  707.         while(Labels[Count])
  708.             Count++;
  709.     }
  710.  
  711.     if(DrawInfo && FontAttr && Labels && Count)
  712.     {
  713.         struct TextFont *Font;
  714.  
  715.         if(Font = OpenFont(FontAttr))
  716.         {
  717.             struct RastPort    RastPort,*RPort = &RastPort;
  718.             LONG            i,Len,MaxWidth;
  719.             UWORD            Lean,Thick;
  720.  
  721.             InitRastPort(RPort);
  722.  
  723.             SetFont(RPort,Font);
  724.  
  725.             Box->Left    = 0;
  726.             Box->Top    = 0;
  727.             Box->Height    = RPort->TxHeight + 11;
  728.  
  729.             Lean = (TextLength(RPort,"A",1) + 1) / 2;
  730.  
  731.             Thick = DrawInfo->dri_Resolution.Y / DrawInfo->dri_Resolution.X;
  732. //            Thick = 2;
  733.  
  734.             if(Thick < 1)
  735.                 Thick = 1;
  736.  
  737.             for(i = MaxWidth = 0 ; i < Count ; i++)
  738.             {
  739.                 if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
  740.                     MaxWidth = Len;
  741.             }
  742.  
  743.             MaxWidth = 2 + (Lean + Thick - 1 + Thick + MaxWidth + Thick + Lean + Thick - 1) + 2;
  744.  
  745.             if(SizeType == GDOMAIN_MINIMUM && Count > 1)
  746.                 Box->Width = 2 * Thick + MaxWidth + (Count - 1) * (Thick * 4) + Thick * 3;
  747.             else
  748.                 Box->Width = 2 * Thick + Count * (MaxWidth + Thick) + Thick * 2;
  749.  
  750.             CloseFont(Font);
  751.  
  752.             Success = TRUE;
  753.         }
  754.     }
  755.  
  756.     va_end(VarArgs);
  757.  
  758.     return(Success);
  759. }
  760.  
  761. ULONG __saveds __asm
  762. LTP_TabClassDispatcher(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
  763. {
  764.     switch(msg->MethodID)
  765.     {
  766.         case OM_NEW:
  767.             return(NewMethod(class,(struct Gadget *)object,(struct opSet *)msg));
  768.  
  769.         case OM_UPDATE:
  770.         case OM_SET:
  771.             return(SetMethod(class,(struct Gadget *)object,(struct opSet *)msg));
  772.  
  773.         case OM_DISPOSE:
  774.             return(DisposeMethod(class,(struct Gadget *)object,msg));
  775.  
  776.         case GM_RENDER:
  777.             return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
  778.  
  779.         case GM_HITTEST:
  780.             return(GMR_GADGETHIT);
  781.  
  782.         case GM_GOINACTIVE:
  783.             return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
  784.  
  785.         case GM_HANDLEINPUT:
  786.             return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  787.  
  788.         case GM_GOACTIVE:
  789.             return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
  790.  
  791.         default:
  792.             return(DoSuperMethodA(class,object,msg));
  793.     }
  794. }
  795.  
  796. #endif    // defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  797.